package com.backend.controller;

import com.backend.conmon.response.CommonResponse2;
import com.backend.req.FileReq;
import com.backend.resp.FileResp;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @Author: tanglingyu
 * @CreateDate: 2024/7/1 18:55
 * @Version: 1.0
 */
@RestController
public class FileController {

  @Value("${file.path:}")
  private String filePath;

  @GetMapping("/list-file")
  @SuppressWarnings({"rawtypes"})
  public CommonResponse2 listFile() {
    final Path path = Paths.get(filePath);
    final File file = path.toFile();
    if (!file.exists()) {
      return CommonResponse2.error("文件夹不存在,文件夹路径=" + filePath + "");
    }
    if (!file.isDirectory()) {
      return CommonResponse2.error(file.getAbsolutePath() + "不是文件夹");
    }
    final FileResp root = new FileResp();
    root.setFileName(file.getName());
    root.setFileSize(file.length());
    root.setFilePath(file.getAbsolutePath());
    recursive(root, file);
    return CommonResponse2.success(root);
  }

  private void recursive(FileResp root, File f) {
    List<FileResp> child = new ArrayList<>();
    root.setFileRespList(child);
    if (f.isDirectory()) {
      final File[] files = f.listFiles();
      if (files != null) {
        for (final File file : files) {
          final FileResp fileResp = new FileResp();
          final String name = file.getName();
          final long length = file.length();
          final String filePath = file.getAbsolutePath();
          fileResp.setFileName(name);
          fileResp.setFileSize(length);
          fileResp.setFilePath(filePath);
          child.add(fileResp);
          if (file.isDirectory()) {
            recursive(fileResp, file);
          }
        }
      }
    } else {
      final String name = f.getName();
      final long length = f.length();
      final String filePath = f.getAbsolutePath();
      FileResp fileResp = new FileResp();
      fileResp.setFileName(name);
      fileResp.setFileSize(length);
      fileResp.setFilePath(filePath);
      child.add(fileResp);
    }
  }

  @PostMapping("/file-detail")
  @SuppressWarnings({"rawtypes"})
  public CommonResponse2 fileDetail(@RequestBody FileReq req, HttpServletResponse response) throws Exception {
    final String type = req.getType();
    final String absPath = req.getAbsPath();
    final Path path = Paths.get(absPath);
    final File file = path.toFile();
    final String mimeType = Files.probeContentType(path);
    if (!file.exists()) {
      return CommonResponse2.error("访问的文件不存在,文件路径=" + filePath + "");
    }
    if (!file.isFile()) {
      return CommonResponse2.error(filePath + "不是文件");
    }
    final byte[] bytes = Files.readAllBytes(file.toPath());
    MediaType mediaType;
    if ("1".equals(type)) {
      final String base64 = Base64Utils.encodeToString(bytes);
      return CommonResponse2.success(base64);
    } else if ("2".equals(type)) {
      HttpHeaders headers = new HttpHeaders();
      mediaType = MediaType.parseMediaType(mimeType);
      headers.setContentType(mediaType);
      final ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, HttpStatus.OK);
      return CommonResponse2.success(responseEntity);
    } else if ("3".equals(type)) {
      response.setContentType("application/octet-stream");
      response.setCharacterEncoding("utf-8");
      response.setHeader("Content-disposition",
          "attachment;filename*=utf-8''" + file.getName());
      try (final ServletOutputStream out = response.getOutputStream()) {
        try (FileInputStream fileInputStream = new FileInputStream(file);) {
          final byte[] bb = IOUtils.toByteArray(fileInputStream);
          IOUtils.write(bb, out);
        }
      }
      return null;
    } else if ("4".equals(type)) {
      HttpHeaders headers = new HttpHeaders();
      headers.setContentDispositionFormData("attachment", file.getName());
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
      final ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, HttpStatus.OK);
      return CommonResponse2.success(responseEntity);
    } else {
      return CommonResponse2.error();
    }
  }
}
